package practica1;

import java.util.Random;

import weka.classifiers.Evaluation;
import weka.classifiers.bayes.NaiveBayes;
import weka.core.Instances;

/**
 * 3. CLASSIFY
 * @author luciarodero
 *
 */
public class Classify {
	
	public Classify(){}
	
	public void classifier(Instances newData) throws Exception{
		
		// 3.0 Train the classifier (estimador)
		NaiveBayes estimador= new NaiveBayes(); //Naive Bayes
		
		// 3.1 Assess the performance of the classifier by means of 10-fold cross-validation 
		Evaluation evaluator = new Evaluation(newData);
		evaluator.crossValidateModel(estimador, newData, 10, new Random(1));

		double acc=evaluator.pctCorrect();
		double inc=evaluator.pctIncorrect();
		double kappa=evaluator.kappa();
		double mae=evaluator.meanAbsoluteError();    
		double rmse=evaluator.rootMeanSquaredError();
		double rae=evaluator.relativeAbsoluteError();
		double rrse=evaluator.rootRelativeSquaredError();
		double confMatrix[][]= evaluator.confusionMatrix();
		
		System.out.println("Correctly Classified Instances  " + acc);
		System.out.println("Incorrectly Classified Instances  " + inc);
		System.out.println("Kappa statistic  " + kappa);
		System.out.println("Mean absolute error  " + mae);
		System.out.println("Root mean squared error  " + rmse);
		System.out.println("Relative absolute error  " + rae);
		System.out.println("Root relative squared error  " + rrse);	
		//3.1.1 Print Confusion Matrix
		for(int i = 0; i < confMatrix.length; i++){
			for(int j = 0; j < confMatrix[0].length; j++){
				System.out.println("Confusion Matrix:"+ confMatrix[i][j]);
			}
		}
		
		// 3.2 Alternatively, assess the performance of the classifier by means of hold-out: leaving the 30% of the data 
		//randomly selected out to test the model 
		
		// 3.2.a Get the test set by randomly selecting the the 30% of the instances
		int trainSize = (int) Math.round(newData.numInstances() * 0.7);
		int testSize = newData.numInstances() - trainSize;

		Instances train = new Instances(newData, 0, trainSize);
		Instances test = new Instances(newData, trainSize, testSize);
		SaveData sd = new SaveData();
		
		//3.2.b Saving test instances in a file
		sd.save("Test.arff", test);
		
		// 3.2.c Train the classifier with the 70\% of the data by means of the Naive Bayes algorithm
		estimador.buildClassifier(train);
		
		// 3.2.d Let the model predict the class for each instance in the test set
		evaluator.evaluateModel(estimador, test);
		double predictions[] = new double[test.numInstances()];
		for (int i = 0; i < test.numInstances(); i++) {
		predictions[i] = evaluator.evaluateModelOnceAndRecordPrediction(estimador, test.instance(i));
		}
		
		
		//3.2.e Save an output file class estimated by the model for each instance of the test
		SaveData sd2 = new SaveData();
		try{
			sd2.predictClass(test, estimador, evaluator, "Test.arff");
		} catch (Exception e){
			e.printStackTrace();
		}
		
		// 3.2.d Assess the performance on the test (igual al 3.1)

	}
}
	
